from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, CreateView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from django.contrib.auth import login, logout
from django.core.mail import send_mail

from .models import News, Category
from .forms import NewsForm, UserRegisterForm, UserLoginForm, ContactForm
from .utils import MyMixin


class HomeNews(MyMixin, ListView):
  model = News
  template_name = 'news/home_news_list.html'
  context_object_name = 'news'
  extra_context = {'title': 'Главная'}
  mixin_prop = 'hello, world'
  paginate_by = 2

  def get_context_data(self, *, object_list=None, **kwargs):
    context = super(HomeNews, self).get_context_data(**kwargs)
    # context['title'] = 'Главная страница'
    context['title'] = self.get_upper('Главная страница')
    context['mixin_prop'] = self.get_prop()
    return context

  def get_queryset(self):
    return News.objects.filter(is_published=True).select_related('category')


class NewsByCategory(MyMixin, ListView):
  model = News
  template_name = 'news/home_news_list.html'
  context_object_name = 'news'
  allow_empty = False
  paginate_by = 2

  def get_context_data(self, *, object_list=None, **kwargs):
    context = super().get_context_data(**kwargs)
    context['title'] = self.get_upper(Category.objects.get(pk=self.kwargs['category_id']))
    return context

  def get_queryset(self):
    return News.objects.filter(category_id=self.kwargs['category_id'], is_published=True).select_related('category')


class ViewNews(DetailView):
  model = News
  context_object_name = 'news_item'
  # template_name = 'news/news_detail.html'
  # pk_url_kwarg = 'news_id'


class CreateNews(LoginRequiredMixin, CreateView):
  form_class = NewsForm
  template_name = 'news/add_news.html'
  # success_url = reverse_lazy('home')
  login_url = '/admin/'
  # success_url = reverse_lazy('home') # вместо login_url = '/admin/'
  # raise_exception = True # вместо login_url = '/admin/'


# def index(request):
#     # news = News.objects.all()
#     news = News.objects.order_by('-created_at')  # сортируем в обратном порядке
#
#     context = {
#         'news': news,
#         'title': 'Список новостей',
#     }
#     return render(request, 'news/index.html', context)


# def get_category(request, category_id):
#     news = News.objects.filter(category_id=category_id)
#     category = Category.objects.get(pk=category_id)
#     context = {
#         'news': news,
#         'category': category
#     }
#     return render(request, 'news/category.html', context)


# def view_news(request, news_id):
#     # news_item = News.objects.get(pk=news_id)
#     news_item = get_object_or_404(News, pk=news_id)
#     context = {
#         'news_item': news_item
#     }
#     return render(request, 'news/view_news.html', context)


# def add_news(request):
#     if request.method == 'POST':
#         form = NewsForm(request.POST)
#         if form.is_valid():
#             # print(form.cleaned_data)
#             # ** - распаковка словарей
#             # news = News.objects.create(**form.cleaned_data)
#             news = form.save()  # Когда форма связанная с моделями
#             # return redirect('home')
#             return redirect(news)
#     else:
#         form = NewsForm()
#     return render(request, 'news/add_news.html', {'form': form})


# Пагинация
def test(request):
  objects = ['john1', 'paul2', 'george3', 'ringo4', 'kolya5', 'vasya6', 'ivan7', 'raul8', 'figo9', 'zidan10',
             'ronaldo11']
  paginator = Paginator(objects, 2)
  page_num = request.GET.get('page', 1)  # если в url адресе нет page, то подставится 1
  page_objects = paginator.get_page(page_num)
  context = {
    'page_obj': page_objects
  }
  return render(request, 'news/test.html', context)


# Регистрация
def register(request):
  if request.method == 'POST':
    form = UserRegisterForm(request.POST)
    if form.is_valid():
      user = form.save()
      login(request, user)
      messages.success(request, 'Вы успешно зарегистрировались')
      return redirect('home')
    else:
      messages.error(request, 'Ошибка регистрации')
  else:
    form = UserRegisterForm()
  return render(request, 'news/register.html', {"form": form})


# Логин
def user_login(request):
  if request.method == 'POST':
    form = UserLoginForm(data=request.POST)
    if form.is_valid():
      user = form.get_user()
      login(request, user)
      return redirect('home')
  else:
    form = UserLoginForm()
  return render(request, 'news/login.html', {"form": form})


# Logout
def user_logout(request):
  logout(request)
  return redirect('login')


# Отправка писем на Email
def send_mail_to_email(request):
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      mail = send_mail(form.cleaned_data['subject'], form.cleaned_data['content'], 'budaev.e@gmail.com',
                       ['evgeniybyrpex@mail.ru'], fail_silently=False)
      if mail:
        messages.success(request, 'Письмо отправлено')
        return redirect('send_mail_to_email')
      else:
        messages.error(request, 'Ошибка отправки')
    else:
      messages.error(request, 'Ошибка отправки письма')
  else:
    form = ContactForm()
  return render(request, 'news/send_mail_to_email.html', {"form": form})


# Captcha
def contact(request):
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      mail = send_mail(form.cleaned_data['subject'], form.cleaned_data['content'], 'budaev.e@gmail.com',
                       ['evgeniybyrpex@mail.ru'], fail_silently=False)
      if mail:
        messages.success(request, 'Письмо отправлено')
        return redirect('contact')
      else:
        messages.error(request, 'Ошибка отправки')
    else:
      messages.error(request, 'Ошибка валидации')
  else:
    form = ContactForm()
  return render(request, 'news/send_mail_to_email.html', {"form": form})
